﻿using System;
using System.Runtime.InteropServices;
using System.Security;
using DupKiller.PInvoke.Structs;

// ReSharper disable UnusedMember.Local
// ReSharper disable InconsistentNaming

namespace FolderBrowserDialogEx
{
	public static class PInvoke
	{

		[DllImport("shell32.dll")]
		internal static extern IntPtr SHBrowseForFolder([In] BrowseInfo lpbi);

		[DllImport("shell32.dll")]
		public static extern int SHGetSpecialFolderLocation(IntPtr hwnd, int csidl, ref IntPtr ppidl);

				[DllImport("shell32.dll")]
		public static extern int SHGetMalloc([Out, MarshalAs(UnmanagedType.LPArray)] PInvoke.IMalloc[] ppMalloc);
		[DllImport("shell32.dll", CharSet = CharSet.Auto)]
		public static extern bool SHGetPathFromIDList(IntPtr pidl, IntPtr pszPath);


//		[DllImport("dwmapi.dll", PreserveSig = false)]
//		public static extern void DwmEnableBlurBehindWindow(
//			 IntPtr hWnd, DWM_BLURBEHIND pBlurBehind);
//
//		[DllImport("dwmapi.dll", PreserveSig = false)]
//		public static extern void DwmExtendFrameIntoClientArea(
//			 IntPtr hWnd, MARGINS pMargins);
//
		[DllImport("dwmapi.dll", PreserveSig = false)]
		public static extern bool DwmIsCompositionEnabled();
//
//		[DllImport("dwmapi.dll", PreserveSig = false)]
//		public static extern void DwmEnableComposition(bool enable);
//
//		[DllImport("dwmapi.dll", PreserveSig = false)]
//		public static extern void DwmGetColorizationColor(
//			 out int pcrColorization,
//			 [MarshalAs(UnmanagedType.Bool)]out bool pfOpaqueBlend);
//
//		[DllImport("dwmapi.dll", PreserveSig = false, SetLastError = true)]
//		public static extern IntPtr DwmRegisterThumbnail(
//			 IntPtr dest, IntPtr source);
//
//		[DllImport("dwmapi.dll", PreserveSig = false)]
//		public static extern void DwmUnregisterThumbnail(IntPtr hThumbnail);
//
//		[DllImport("dwmapi.dll", PreserveSig = false)]
//		public static extern void DwmUpdateThumbnailProperties(
//			 IntPtr hThumbnail, DWM_THUMBNAIL_PROPERTIES props);
//
//		[DllImport("dwmapi.dll", PreserveSig = false)]
//		public static extern void DwmQueryThumbnailSourceSize(
//			 IntPtr hThumbnail, out Size size);
//
//		[StructLayout(LayoutKind.Sequential)]
//		public class DWM_THUMBNAIL_PROPERTIES
//		{
//			public uint dwFlags;
//			public RECT rcDestination;
//			public RECT rcSource;
//			public byte opacity;
//			[MarshalAs(UnmanagedType.Bool)]
//			public bool fVisible;
//			[MarshalAs(UnmanagedType.Bool)]
//			public bool fSourceClientAreaOnly;
//			public const uint DWM_TNP_RECTDESTINATION = 0x00000001;
//			public const uint DWM_TNP_RECTSOURCE = 0x00000002;
//			public const uint DWM_TNP_OPACITY = 0x00000004;
//			public const uint DWM_TNP_VISIBLE = 0x00000008;
//			public const uint DWM_TNP_SOURCECLIENTAREAONLY = 0x00000010;
//		}
//
		[StructLayout(LayoutKind.Sequential)]
		public class MARGINS
		{
			public int cxLeftWidth, cxRightWidth,
						  cyTopHeight, cyBottomHeight;

			public MARGINS()
			{

			}

			public MARGINS(int i)
				: this(i, i, i, i)
			{

			}

			public MARGINS(int left, int top, int right, int bottom)
			{
				cxLeftWidth = left; cyTopHeight = top;
				cxRightWidth = right; cyBottomHeight = bottom;
			}
		}
//
//		[StructLayout(LayoutKind.Sequential)]
//		public class DWM_BLURBEHIND
//		{
//			public uint dwFlags;
//			[MarshalAs(UnmanagedType.Bool)]
//			public bool fEnable;
//			public IntPtr hRegionBlur;
//			[MarshalAs(UnmanagedType.Bool)]
//			public bool fTransitionOnMaximized;
//
//			public const uint DWM_BB_ENABLE = 0x00000001;
//			public const uint DWM_BB_BLURREGION = 0x00000002;
//			public const uint DWM_BB_TRANSITIONONMAXIMIZED = 0x00000004;
//		}
//
//		[StructLayout(LayoutKind.Sequential)]
//		public struct RECT
//		{
//			public int left, top, right, bottom;
//
//			public RECT(int left, int top, int right, int bottom)
//			{
//				this.left = left; this.top = top;
//				this.right = right; this.bottom = bottom;
//			}
//		}
//
//		[DllImport("dwmapi.dll")]
//		static extern int DwmExtendFrameIntoClientArea(IntPtr handle, ref PInvokeUI.MARGINS margins);
//
//		public const int WM_NCLBUTTONDOWN = 0xA1;
//		public const int HT_CAPTION = 0x2;
//
		//[DllImport("user32.dll")]
		//public static extern int SendMessage(IntPtr hWnd, int msg, int wParam, int lParam);
//		[DllImport("user32.dll")]
//		public static extern bool ReleaseCapture();

		public static bool GlassEnabled
		{
			get { return Environment.OSVersion.Version.Major >= 6 && DwmIsCompositionEnabled(); }
		}

		public static bool MakeGlassWindow(this IntPtr handle)
		{
			if (GlassEnabled)
			{
				var margins = new MARGINS(-1);

				PInvokeUI.DwmSetWindowAttribute()

				DwmExtendFrameIntoClientArea(handle, ref margins);
				return true;
			}
			return false;
		}
//
//		public static bool MakeGlassWindow(this System.Windows.Forms.Form winForm)
//		{
//			return winForm.Handle.MakeGlassWindow();
//		}
//
//		public static bool MakeGlassWindow(this Window wpfWindow, Brush defaultBackground = null)
//		{
//			if (GlassEnabled)
//			{
//				var mainWindowSrc = HwndSource.FromHwnd(new WindowInteropHelper(wpfWindow).Handle);
//				if (mainWindowSrc != null)
//				{
//					mainWindowSrc.CompositionTarget.BackgroundColor = Colors.Transparent;
//					var margins = new PInvokeUI.MARGINS(-1);
//					DwmExtendFrameIntoClientArea(mainWindowSrc.Handle, ref margins);
//					wpfWindow.Background = Brushes.Transparent;
//
//					return true;
//				}
//			}
//
//			wpfWindow.Background = defaultBackground;
//			return false;
//		}
//
//		public static void SimulateMouseDonwOnTitleBar(this Window wpfWindow)
//		{
//			ReleaseCapture();
//			SendMessage(new WindowInteropHelper(wpfWindow).Handle, WM_NCLBUTTONDOWN, HT_CAPTION, 0);
//		}
//	}
//


		[DllImport("user32.dll", CharSet = CharSet.Auto)]
		public static extern IntPtr SendMessage(HandleRef hWnd, int msg, int wParam, string lParam);

		[DllImport("user32.dll", CharSet = CharSet.Auto)]
		public static extern IntPtr SendMessage(HandleRef hWnd, int msg, int wParam, int lParam);

		[DllImport("user32.dll", SetLastError = true)]
		public static extern IntPtr FindWindowEx(HandleRef hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);

		[DllImport("user32.dll", SetLastError = true)]
		public static extern Boolean SetWindowText(IntPtr hWnd, String text);
//		
//
		[ComImport, Guid("00000002-0000-0000-c000-000000000046"), SuppressUnmanagedCodeSecurity, InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
		public interface IMalloc
		{
			[PreserveSig]
			IntPtr Alloc(int cb);
			[PreserveSig]
			IntPtr Realloc(IntPtr pv, int cb);
			[PreserveSig]
			void Free(IntPtr pv);
			[PreserveSig]
			int GetSize(IntPtr pv);
			[PreserveSig]
			int DidAlloc(IntPtr pv);
			[PreserveSig]
			void HeapMinimize();
		}

		//		[StructLayout(LayoutKind.Sequential)]
		//		private struct SHFILEINFO
		//		{
		//			public IntPtr hIcon;
		//			public IntPtr iIcon;
		//			public uint dwAttributes;
		//			[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
		//			public string szDisplayName;
		//			[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 80)]
		//			public string szTypeName;
		//		}
		//
		//		public const uint SHGFI_ICON = 0x100;
		//		public const uint SHGFI_LARGEICON = 0x0; // Large icon
		//		public const uint SHGFI_SMALLICON = 0x1; // Small icon
		//		public const uint USEFILEATTRIBUTES = 0x000000010; // when the full path isn't available
		//		[DllImport("shell32.dll")]
		//		static extern IntPtr SHGetFileInfo(string pszPath, uint dwFileAttributes, ref SHFILEINFO psfi, uint cbSizeFileInfo, uint uFlags);
		//		[DllImport("User32.dll")]
		//		static extern int DestroyIcon(IntPtr hIcon);
		//		[DllImport("shell32.dll", CharSet = CharSet.Auto)]
		//		static extern int ExtractIconEx(string exeFileName, int iconIndex, ref IntPtr iconLarge, ref IntPtr iconSmall, int icons);
		//		public static Icon GetSmallIcon(string fileName)
		//		{
		//			return GetIcon(fileName, false);
		//		}
		//
		//		public static Icon GetIcon(string fileName, bool large)
		//		{
		//			IntPtr hImgSmall; //the handle to the system image list
		//			SHFILEINFO shinfo = new SHFILEINFO();
		//			hImgSmall = SHGetFileInfo(fileName, 0, ref shinfo, (uint)Marshal.SizeOf(shinfo), SHGFI_ICON | (large?SHGFI_LARGEICON: SHGFI_SMALLICON) /*| USEFILEATTRIBUTES*/);
		//The icon is returned in the hIcon member of the shinfo struct
		//			Icon icon = (Icon)Icon.FromHandle(shinfo.hIcon).Clone();
		//			DestroyIcon(shinfo.hIcon);
		//			return icon;
		//		}
		//
		//		public static Icon GetLargeIcon(string fileName)
		//		{
		//			return GetIcon(fileName, true);
		//		}
		//				const uint IO_REPARSE_TAG_MOUNT_POINT = 0xA0000003; // Moiunt point or junction, see winnt.h
		//		const uint IO_REPARSE_TAG_SYMLINK = 0xA000000C; // SYMLINK or SYMLINKD (see http://wesnerm.blogs.com/net_undocumented/2006/10/index.html)
		//		const UInt32 SE_PRIVILEGE_ENABLED = 0x00000002;
		//		const string SE_BACKUP_NAME = "SeBackupPrivilege";
		//		const uint FILE_FLAG_BACKUP_SEMANTICS = 0x02000000;
		//		const uint FILE_FLAG_OPEN_REPARSE_POINT = 0x00200000;
		//		const uint FILE_DEVICE_FILE_SYSTEM = 9;
		//		const uint FILE_ANY_ACCESS = 0;
		//		const uint METHOD_BUFFERED = 0;
		//		const int MAXIMUM_REPARSE_DATA_BUFFER_SIZE = 16*1024;
		//		const uint TOKEN_ADJUST_PRIVILEGES = 0x0020;
		//		const int FSCTL_GET_REPARSE_POINT = 42;
		//
		// This is the official version of the data buffer, see http://msdn2.microsoft.com/en-us/library/ms791514.aspx
		// not the one used at http://www.flexhex.com/docs/articles/hard-links.phtml
		//		[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
		//		struct REPARSE_DATA_BUFFER
		//		{
		//			public uint ReparseTag;
		//			public short ReparseDataLength;
		//			public short Reserved;
		//			public short SubsNameOffset;
		//			public short SubsNameLength;
		//			public short PrintNameOffset;
		//			public short PrintNameLength;
		//			[MarshalAs(UnmanagedType.ByValArray, SizeConst = MAXIMUM_REPARSE_DATA_BUFFER_SIZE)] public char[] ReparseTarget;
		//		}
		//
		//		[StructLayout(LayoutKind.Sequential)]
		//		struct LUID
		//		{
		//			public UInt32 LowPart;
		//			public Int32 HighPart;
		//		}
		//
		//		[StructLayout(LayoutKind.Sequential)]
		//		struct LUID_AND_ATTRIBUTES
		//		{
		//			public LUID Luid;
		//			public UInt32 Attributes;
		//		}
		//
		//		struct TOKEN_PRIVILEGES
		//		{
		//			public UInt32 PrivilegeCount;
		//
		//			[MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)] // !! think we only need one
		//				public LUID_AND_ATTRIBUTES[] Privileges;
		//		}
		//
		//		[DllImport("kernel32.dll", ExactSpelling = true, SetLastError = true, CharSet = CharSet.Auto)]
		//		[return: MarshalAs(UnmanagedType.Bool)]
		//		static extern bool DeviceIoControl(
		//			IntPtr hDevice,
		//			uint dwIoControlCode,
		//			IntPtr lpInBuffer,
		//			uint nInBufferSize,
		//			out REPARSE_DATA_BUFFER outBuffer,
		//			uint nOutBufferSize,
		//			out uint lpBytesReturned,
		//			IntPtr lpOverlapped);
		//
		//		[DllImport("Kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
		//		static extern IntPtr CreateFile(
		//			string fileName,
		//			[MarshalAs(UnmanagedType.U4)] FileAccess fileAccess,
		//			[MarshalAs(UnmanagedType.U4)] FileShare fileShare,
		//			int securityAttributes,
		//			[MarshalAs(UnmanagedType.U4)] FileMode creationDisposition,
		//			uint flags,
		//			IntPtr template);
		//
		//		[DllImport("advapi32.dll", SetLastError = true)]
		//		[return: MarshalAs(UnmanagedType.Bool)]
		//		static extern bool OpenProcessToken(IntPtr ProcessHandle,
		//			UInt32 DesiredAccess, out IntPtr TokenHandle);
		//
		//		[DllImport("kernel32.dll")]
		//		static extern IntPtr GetCurrentProcess();
		//
		//		[DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Auto)]
		//		[return: MarshalAs(UnmanagedType.Bool)]
		//		static extern bool LookupPrivilegeValue(string lpSystemName, string lpName,
		//			out LUID lpLuid);
		//
		//		[DllImport("advapi32.dll", SetLastError = true)]
		//		[return: MarshalAs(UnmanagedType.Bool)]
		//		static extern bool AdjustTokenPrivileges(IntPtr TokenHandle,
		//			[MarshalAs(UnmanagedType.Bool)] bool DisableAllPrivileges,
		//			ref TOKEN_PRIVILEGES NewState,
		//			Int32 BufferLength,
		//ref TOKEN_PRIVILEGES PreviousState,					!! for some reason this won't accept null
		//			IntPtr PreviousState,
		//			IntPtr ReturnLength);
		//
		//		[DllImport("kernel32.dll", SetLastError = true)]
		//		[return: MarshalAs(UnmanagedType.Bool)]
		//		static extern bool CloseHandle(IntPtr hObject);
		//
		//		public enum TagType
		//		{
		//			None = 0,
		//			MountPoint = 1,
		//			SymbolicLink = 2,
		//			JunctionPoint = 3
		//		}

		//

		//
		//		[DllImport("user32.dll")]
		//		static extern bool SetLayeredWindowAttributes(IntPtr hwnd, uint crKey, byte bAlpha, uint dwFlags);
		//		[DllImport("user32.dll")]
		//		static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);
		//
		//		public const int GWL_EXSTYLE = -20;
		//		public const int WS_EX_LAYERED = 0x80000;
		//		public const int LWA_ALPHA = 0x2;
		//		public const int LWA_COLORKEY = 0x1;
		//		[DllImport("user32.dll", SetLastError = false)]
		//		static extern int GetWindowLong(IntPtr hWnd, int nIndex);
		//
		internal static IMalloc GetSHMalloc()
				{
					var ppMalloc = new IMalloc[1];
					SHGetMalloc(ppMalloc);
					return ppMalloc[0];
				}
		//
		//
	}
}